﻿using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.IO;

namespace SNSpirit.IO
{
    /// <summary>
    /// Track all temp file
    /// Singleton object
    /// </summary>
    internal class InternalTemporaryStorageController
    {
        #region singletion & ctor

        private static readonly object _syncRoot = new object();

        private static volatile InternalTemporaryStorageController _instance;

        public static InternalTemporaryStorageController Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_syncRoot)
                    {
                        if (_instance == null)
                            _instance = new InternalTemporaryStorageController();
                    }
                }
                return _instance;
            }
        }

        private InternalTemporaryStorageController()
        {
        }

        #endregion

        public string GetNewTempFilename(RepositoryIdentity id)
        {
            if (id == null)
                throw new ArgumentNullException("id");
            var repository = this.GetOrCreateFileRepository(id);
            if (repository != null)
                return repository.GetNewRandomFileName();
            else
                throw new InvalidOperationException();
        }

        public void CleanRepository(RepositoryIdentity id)
        {
            if (id == null)
                throw new ArgumentNullException("id");
            var repository = this.GetOrCreateFileRepository(id);
            if(repository != null)
                repository.Clean();
        }

        #region private

        private readonly ConcurrentDictionary<RepositoryIdentity, FileRepository> _repositories 
            = new ConcurrentDictionary<RepositoryIdentity, FileRepository>();
        
        private FileRepository GetOrCreateFileRepository(RepositoryIdentity id)
        {
            return this._repositories.GetOrAdd(id, new Func<RepositoryIdentity, FileRepository>(i => new FileRepository(i)));
        }

        #endregion
    }
}
